import pandas as pd
import re

#保存人员区分信息
staff_area = {
    '宝安' : ['韦泽龙','韦辉辉','黄华义','李德飞','占镐锋','林奇','李永林','苏健金','林文斌','冯宇标','罗峰','罗锋','彭帮忠','丘江','陈卫国','陈雾','雷万成','温晖','张信平','梁远清','刘金鹏','黄瑞钦','陈昌远'],
    '福田' : ['苏辉煌','刘后华','林艺','马宗超','饶亮','谢培强','魏宇佳','罗习海','魏宏','周传光','林丹琪','彭柳荣','龚海林','方敏','罗建','张灿州','莫尊绍','姚峰','林梓涵','邓辉龙','王梓荣','黄浩然','王云','毕伟豪','林志勇','刘祖栎','毛楚铭','张飞','崔二朋','张加雨','陈业威','陈佳椋','黄志浪'],
    '光明' : ['王扬春','吴廷光','陈义','梁宽','鲁进伟','廖伟明','李义群','邓亮','丘满昌','刘达斌','周承豪','邓泉','刘付新杰','黄亚海','张广俊','魏文','甘国辉'],
    '龙岗' : ['黄辉','丘淼','邓华强','李伟伟','刘纯才','朱健伟','朱键伟','张富明','余少群','黎绍金','王学谦','李绰德','陈洪华','林旭波','罗铭贵','邓护峰','邓护锋','谢复荣','陈文彦','陈凤娇','谷兰红','周家龙','张俊华','郭旋','卢志才','刘太松','王毅广','林豪杰','黄文华','朱智琦','王锦城','林秀丽','骆江顺','杨志辉','钟玉霞','郑文伟','马俊泳','林小钻','张福源','邓运财','李云峰','李秀忠','陈灏霖','苏尚居','杨健','梁荣伟'],
    '龙华' : ['支锦文','叶仕锦','熊进','陈嵩锋','阿扎玛提','李文锋','洪灿坚','顾绍飞','邹胜华','陈明','葛长根','袁海堂','张伟传','郑武滔','郑武略','刘社军'],
    '罗湖' : ['黎志腾','彭奕明','范志锐','刘开铭','余建安','曹志辉','杨文景','张壮豪','刘明富','黄锦塘','曾运兵','杨乾'],
    '南山' : ['何小均','张瑶','杨宝峰','吕翀','吕�','陈学文','曾旭辉','邢凯','洪波','蓝伟方','黄国栋','周世晓','王国杰','陈永健','查捷','陈志环','何文彬','吴金财','周爽','郭江','翁建武','黄远华','林烁','刘俊杰','康旭发','吴鸿炯','邱俊锋','邓嘉壕','欧堂杰','黄文基','郑鸿进'],
    '坪大' : ['黄永茂','刘诗成','钟伟龙','周磊','杨世强','李剑勇','黄康隆','欧伟波','高艳德','官艳德','肖竣'],
    '蛇口前海' : ['罗军华'],
    '盐田' : ['郭志勇','林晓祥','余国均','邓志超','潘嘉明','廖发辉','杨海辉','莫秋辉','刘光伟','肖俊豪']
}

#任务类别提取函数
def task_category1(task_name:str):
    if '/' not in task_name:
        return '标题填写不规范！'
    original = task_name.split('/')[-2].split('-')[-2:]
    original = '-'.join(original)
    for i in ['-1台', '-2台', '-3台', '-4台', '-5台', '-6台', '-7台', '-8台', '-9台']:
        if i in original.split('-')[-1]:
            return '标题填写不规范！'
    if len(original) > 9:
        if len(original.split('-')[-1]) >= 12 or len(original.split('-')[-1]) < 2:
            return '标题填写不规范！'
        return original.split('-')[-1]
    else:
        return original
    
def task_category(task_name:str):
    task_name = task_name.replace('--', '-')
    for i in ['-室分', '-BBU', '-基站']:
        if i in task_name:
            return task_category1(task_name)
    if '-站址' not in task_name:
        for i in [' ', '-单', '-站', '-台', '-天', '-1台', '-2台', '-3台', '-4台', '-5台', '-6台', '-7台', '-8台', '-9台', '-1天', '-2天', '-3天', '-4天', '-5天', '-6天', '-7天', '-8天', '-9天']:
            task_name = task_name.replace(i, '')
        task_name = task_name.split('-')
    else:
        for i in [' ', '-单', '-台', '-天', '-1台', '-2台', '-3台', '-4台', '-5台', '-6台', '-7台', '-8台', '-9台', '-1天', '-2天', '-3天', '-4天', '-5天', '-6天', '-7天', '-8天', '-9天']:
            task_name = task_name.replace(i, '')
        task_name = task_name.split('-')     
    task_name = task_name[len(task_name)-2:len(task_name)]
    task_name = '-'.join(task_name)
    result = re.match('.*?-(?P<task>.*?)/', task_name)
    if result is None:
        return '标题填写不规范！'
    if len(result.group('task')) > 12 or len(result.group('task')) < 2:
        return '标题填写不规范！'
    elif result is not None:
        return result.group('task')
    else:
        return '标题填写不规范！'

#分值提取函数
def score(task_name:str):
    result = re.match('.*?(?P<score>[0-9]{1,3})分', task_name)
    if result is not None:
        return result.group('score')
    else:
        return 'None'
    
#获取值对应的键函数
def get_key(dic, val):
    for key, value in dic.items():
        if val in value:
            return key
    
#清洗任务类型函数
def wash(task_category:str):
    wash_dic = {
        '现场验收-室分' : ['室分现场验收', '室分验收', '现场验收-室分'],
        '拔尾纤' : ['拆尾纤', '拔尾纤', '尾纤', '拔C网光路'],
        '拆设备' : ['室分拆设备', '室分设备拆除', '室分拆站', '拆除设备', '设备拆除', '拆设备'],
        '区分支撑' : ['区分支撑', '会议支撑', '区分'],
        '信源迁改等割接配合' : ['信源迁改'],
        '设备下电' : ['设备下电', '设务下电', '下电'],
        '站址电租费现场检查' : ['站址电租费现场检查', '站址电租费现场核查'],
        '室外拆站，含配套' : ['室外拆站，含配套'],
        '室外拆站，不含配套' : ['室外拆站，不含配套'],
        '微波站S1故障核查' : ['微波站S1故障核查', '微波'],
        'NR设备安装' : ['NR设备替换', 'NR替换安装', '替换'],
        '基站现场验收' : ['基站现场验收-站', '基站现场验收']
    }

    #添加原则：字符长度较长的放前面
    wash_list = ['站址电租费现场检查', '站址电租费现场核查', '微波站S1故障核查', '室外拆站，不含配套', '基站现场验收-站', '现场验收-室分', '室外拆站，含配套', '基站现场验收', '室分现场验收', 'NR设备替换', 'NR替换安装', '室分设备拆除', '拔C网光路', '室分拆站', '室分验收', '拆除设备', '设备拆除', '区分支撑', '会议支撑', '信源迁改', '设备下电', '设务下电', '拆设备', '拆尾纤', '拔尾纤', '替换', '尾纤', '下电', '区分', '微波']
    
    for i in wash_list:
        if i in task_category:
            return get_key(wash_dic, i)
    return task_category

#将英文月份替换成数字月份函数
def numerical_month(x):
    numerical_mon = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
    english_mon = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec']
    for i in range(12):
        x = x.replace(english_mon[i], numerical_mon[i])
    return x

#在此自定义要处理的excel表
sheet_name = '指挥任务0102.xlsx'
df = pd.read_excel(sheet_name, dtype='object')

#创建【清单】子表
df1 = df[['工单号', '结束时间', '实施人部门名称', '施工人员名称', '实施比例', '标题']]
#去除无效数据
df1 = df1.drop(index=df1[(df1.施工人员名称 == '姚旭茹') | (df1.施工人员名称 == '魏文州')].index.tolist())
#新增【工单号&施工人员名称】列
df1.insert(0, '工单号&施工人员名称', 0)
df1['工单号&施工人员名称'] = df1['工单号'] + df1['施工人员名称']
#根据【工单号&施工人员名称】去重
df1.drop_duplicates(subset=['工单号&施工人员名称'], keep='last', inplace=True)
#从实施部门名称中分理出具体部门
df1['实施人部门名称'] = df1['实施人部门名称'].apply(lambda x:x.split('/')[-2].split('（')[-2] if len(x.split('/')[-2].split('（'))==2 else x.split('/')[-2].split('（')[-1])
#从标题中分离出任务类型
df1.insert(len(df1.columns)-1, '任务类型', df1['标题'].astype(str).apply(lambda x:task_category(x)))
#从标题中分离出分值
df1.insert(len(df1.columns)-1, '分值', df1['标题'].apply(lambda x:x+'分').apply(lambda x:score(x)))
#标准化任务类型描述
df1['任务类型'] = df1['任务类型'].astype(str).apply(lambda x:wash(x))
#从结束时间中分离出来年份和月份
df1['结束时间'] = df1['结束时间'].astype(str).apply(lambda x:'-'.join(re.split(r'[ ]+', x)[-2::-2]))
df1['结束时间'] = df1['结束时间'].astype(str).apply(lambda x:numerical_month(x))
#移动标题列的位置
p = df1.pop('标题')
df1.insert(4, '标题', p)

#拆分多人任务行
df1.insert(4, '人员数量', df1['施工人员名称'].astype(str).apply(lambda x:len(x.split(','))))
df1.insert(5, '切分位置', 0)
df1_temp = df1.copy(deep=True)
for i in range(2, df1['人员数量'].max()+1):
    df1_add = df1_temp.query(f"人员数量=={i}")
    for j in range(i-1):
        df1_add['切分位置'] = df1_add['切分位置'].apply(lambda x:j+1)
        df1 = pd.concat([df1, df1_add], ignore_index=True)
df1['切分位置'] = df1['切分位置'].astype(int)
df1['人员数量'] = df1['人员数量'].astype(int)
df1['实施比例'] = df1['实施比例'].astype(str)

#对【实施比例】列的空白进行填充（默认填充100）
df1['实施比例'].fillna(100, inplace=True)
df1['实施比例'] = df1['实施比例'].apply(lambda x:x.replace('nan', '100'))

#【分值】列类型转化为float
df1['分值'] = df1['分值'].astype(float).apply(lambda x:'%.2f' % x).astype(float)

#拆分施工人员名称和实施比例
for i in range(df1.shape[0]):
    df1.loc[i, '施工人员名称'] = df1.loc[i, '施工人员名称'].split(',')[df1.loc[i, '切分位置']]
    df1.loc[i, '实施比例'] = df1.loc[i, '实施比例'].split(',')[df1.loc[i, '切分位置']]

# 【实施比例】列类型转化为float（保留两位小数）
df1['实施比例'] = df1['实施比例'].astype(float).apply(lambda x: '%.2f' % x).astype(float)

#删除【人员数量】、【切分位置】列，以免影响groupby
df1 = df1.drop(['人员数量', '切分位置'], axis=1)

#更新【工单号&施工人员名称】列内容，以免影响groupby
df1['工单号&施工人员名称'] = df1['工单号'] + df1['施工人员名称']

#单独提取出【工单号&施工人员名称】、【实施比例】,生成每单每人的实施比例
df1_ssbl = df1[['工单号&施工人员名称', '实施比例']].groupby(['工单号&施工人员名称']).sum(numeric_only=True)

#单独提取出【工单号】、【实施比例】，生成每单的总实施
df1_ssbl_sum = df1[['工单号', '实施比例']].groupby(['工单号']).sum(numeric_only=True)

#根据【工单号&施工人员名称】再次去重
df1.drop_duplicates(subset=['工单号&施工人员名称'], keep='last', inplace=True)

#删除现在错误的【实施比例】列
df1 = df1.drop(['实施比例'], axis=1)

#根据【工单号&施工人员名称】右连接 df1 和 df1_ssbl（实施比例）
df1 = pd.merge(df1, df1_ssbl, on='工单号&施工人员名称')

#根据【工单号】右连接 df1 和 df1_ssbl_sum（总实施比例）
df1 = pd.merge(df1, df1_ssbl_sum, on='工单号')

#计算分值
df1['分值'] = df1['实施比例_x'] / df1['实施比例_y'] * df1['分值']

#分值四舍五入保留2位小数
df1['分值'] = df1['分值'].round(2)

#删除不要的列
df1 = df1.drop(['工单号&施工人员名称', '实施比例_x', '实施比例_y'], axis=1)

#加入【区分】、【任务子类型】字段
df1.insert(3, '区分', '')
df1.insert(7, '任务子类型', '')
df1['区分'] = df1['施工人员名称'].apply(lambda x:get_key(staff_area, x))

#把'吕�'替换成'吕翀'
df1.replace('吕�', '吕翀', inplace=True)

#创建【统计】子表
df2 = df1.copy(deep=True)
df2['分值'] = df2['分值'].astype(float)
df2.insert(3, '工单数量', 1)
df2 = df2.groupby(['结束时间', '实施人部门名称', '区分', '施工人员名称', '任务类型', '任务子类型']).sum(numeric_only=True)
df3 = df2.groupby(['施工人员名称']).sum(numeric_only=True)

#输出报表
with pd.ExcelWriter('指挥任务工单统计.xlsx') as writer:
    df1.to_excel(writer, sheet_name='清单', index=False)
    df2.to_excel(writer, sheet_name='统计1')
    df3.to_excel(writer, sheet_name='统计2')
#
# #输出带有标题填写不规范标记的原始数据以便自纠(可选功能，需要使用可自行解除注释)
# # def if_normal(task_name):
# #     if task_name == '标题填写不规范！':
# #         return '不规范'
# #     else:
# #         return '规范'
# # df.insert(0, '标题是否规范（将标题修正后可将此列删除再导入脚本运行）', 0)
# # df['标题是否规范（将标题修正后可将此列删除再导入脚本运行）'] = df['标题'].apply(lambda x:if_normal(task_category(x)))
# # df.to_excel('(自纠)' + sheet_name, index=False)